import pygame

from PyPixelCore.Setting import *
from PyPixelCore.block.Bar import Bar
from PyPixelCore.panel.Panel import Panel

"""
    PanelList --> Panel --> BaseBlock
    一个纵向界面,维护着各种按钮, 块等控件
    可以在特定时间, 特定地点展示出来的列表

    **由于存在大小改变之内的事件,每次脏绘制都等于重绘,严重影响绘制效率
    功能:
        不支持panel的嵌套
        不支持自动大小
        支持焦点
        支持帧动画
        通过脏精灵更新
        维护内部精灵组
        支持鼠标滚轮事件
        支持区域化加载

"""


class PanelList(Panel):
    def __init__(self,
                 width,  # 限制的宽度
                 height,  # 限制的高度
                 point_x=0,  # 起始的x点
                 point_y=0,  # 起始的y点
                 border_width=3,  # 边框宽度
                 layer=1,  # 层的位置
                 is_alpha=False,
                 border_color=Color_type.BLACK,
                 bk_color=Color_type.WHITE):

        # self.show_image = None
        self.sum_height = height
        self.block_interval = 20
        self.bar = None
        self.bar_offset = 0.0

        super().__init__(point_x, point_y, width, height, border_width, layer, is_alpha,
                         border_color, bk_color)

        # self.set_frame_animation(change_example)

    def _reload_image_first(self):
        self._reload_bk_image()

    def _do_layout(self):  # 纵向在空间里排序
        # print("split__________________________________________________________")
        sum_height = 0 + self.block_interval + self.border_width
        for sprite in self.sprites_group.sprites():
            if isinstance(sprite, Bar):
                sprite.kill()
                continue
            sprite.rect.x = (self.width - sprite.rect.width) / 2 + self.border_width
            sprite.rect.y = sum_height
            sprite.collision_rect = sprite.rect.copy()
            sprite.collision_rect.x += self.point_x
            sprite.collision_rect.y += self.point_y
            # print(sprite.collision_rect)
            sum_height += sprite.rect.height + self.block_interval

        # 超出列表可视范围，需要添加bar
        if sum_height > self.height:
            self.sum_height = sum_height
            # if self.sprites_group.has(self.bar):
            #     self.bar.kill()

            proportion = (self.height / sum_height) * self.height  # 视窗长度
            self.bar = Bar(point_x=self.rect.width - self.border_width - 10, point_y=self.border_width
                           , real_height=self.height, bar_height=proportion, border_width=0)  # bar默认的宽度为10
            self.bar.collision_rect.x += self.point_x
            self.bar.collision_rect.y += self.point_y
            self.sprites_group.add(self.bar)

        return self.bar

    def add_sprites(self, *sprites):
        for sprite in sprites:
            # if sprite.type in []
            self.sprites_group.add(sprite)
        self._do_layout()
        self.is_dirty = True
        self.reload_image()

    def reload_image(self):
        for sprite in self.sprites_group.sprites():
            if sprite.is_dirty:
                # 修正位移量
                if isinstance(sprite, Bar):
                    self.bar_offset = (self.sum_height - self.height) * sprite.bar_process
                self.is_dirty = True
            sprite.update()
        if not self.is_dirty:
            return

        self.is_dirty = False
        # 重新更新图像
        self.image = self.bk_image.copy()
        # 绘制
        for sprite in self.sprites_group.sprites():
            if isinstance(sprite, Bar):
                self.bar.draw(self.image)
            else:
                real_y = sprite.rect[1] - self.bar_offset
                if real_y >= 0 or real_y <= self.height:  # 剪枝,只保留界内绘制
                    self.image.blit(sprite.image,
                                    (sprite.rect[0], real_y, sprite.rect[2], sprite.rect[3]))
                sprite.collision_rect.y = sprite.rect[1] - self.bar_offset + self.rect[1]
            # sprite.draw(self.image)

        # 绘制边框
        pygame.draw.rect(self.image, self.border_color, (0, 0, self.rect.width, self.rect.height),
                         width=self.border_width)

    def draw(self, surf):
        surf.blit(self.image, self.rect)
        if show_rect_collision:
            pygame.draw.rect(surf, Color_type.RED, self.rect, width=block_surface_width)

    def wheel_down_animation(self):
        if not self.bar:
            return
        if self.bar.bar_process == 0:
            return
        process_add = bar_sensitive / self.sum_height
        self.bar.bar_process -= process_add
        if self.bar.bar_process < 0:
            self.bar.bar_process = 0.0
        self.bar.is_dirty = True

    def wheel_up_animation(self):
        if not self.bar:
            return
        if self.bar.bar_process == 1:
            return
        process_add = bar_sensitive / self.sum_height
        self.bar.bar_process += process_add
        if self.bar.bar_process > 1:
            self.bar.bar_process = 1
        self.bar.is_dirty = True


def change_example(self):
    self.bar_offset += 0.1
    self.is_dirty = True
